1. Field of the Invention
The invention relates to securing applets loaded into computing devices, especially security tokens, against fault attacks.
2. Description of the Related Art
Fault attacks comprise provoking a physical perturbation in a computing device. Attackers typically wish to create a perturbation in a very accurately defined zone of a component of the computing device (e.g. a part of an EEPROM memory chip storing certain interesting data), at a very accurately defined time (in order to know what the computing device is doing when it is attacked and e.g. to be able to target a specific function). Many different techniques exist to create such perturbations. For example it is possible to:                alter the power supply (e.g. change the Vcc tension from the expected value, for example 5 volts, to a wrong value, e.g. a much higher value such as 50 Volts, possibly during a very short time, in order to create a glitch),        modify the clock (e.g. overclocking, i.e. increase substantially the clock frequency at a time when an attacker wishes to create a fault),        modify the temperature (e.g. heat the chip or parts of the chip of the computing device, from ambient temperature to for example 100° C.),        subject a chip of the computing device to a laser beam, or to radiations such as X-Ray radiation, UV radiation, light radiations, or any form of electromagnetic radiations,        subject a computing device to vibrations, or        apply chemical products on parts of a chip.        
The aim of faults attacks may be in particular to crack a cryptographic algorithm and recover cryptographic keys, or to circumvent certain protections implemented by the computing device. For example, when a countermeasure is invoked, a fault attack may prevent the countermeasure from working properly.
One type of fault attacks which is particularly efficient is illustrated below, on a very simple applet which java source code is shown on the left side, while the corresponding java bytecodes are shown on the right side.
Java code:Bytecode:bParameter =(short) 1;sconst_1;sstore_2;checkSecurity(bParameter);aload_0;sload_2;invokespecial 3;if (bParameter == (short) 2)sload_2;sconst_2;if_scmpne L5;{...}
In this simple applet, if the invokespecial bytecode is skipped during code interpretation (e.g. by transforming the invokespecial bytecode into an innocuous bytecode thanks to a fault attack), the method checkSecurity is not called, while the rest of the applet is executed normally.
A security token is typically an electronic device, which is light and small in order to be easily carried by a user (fits easily in a pocket). It is most often personal. In general, a security token is a resource constrained device, in that at least one of the following is true: its processor is not very powerful, it has little memory, it does not have a source of power (battery etc.) nor a user interface, i.e. in order to interact with the security token a user typically needs to connect the security token (either in contact or in contact-less mode) with a terminal, which provides some power as well as means to input data into the security token and/or to display or otherwise communicate to the user (e.g. with a sound card, an LED, a buzzer, a vibrator, etc.) certain information sent by the security token. More elaborate security tokens may embed a battery, and/or have input/output capabilities such as a small pinpad, or a small LCD.
The most widespread example of security token is probably the smart card. Billions of smart cards are used in the world, and allow card holders (people carrying the smart card) to authenticate themselves e.g. to a financial institution (e.g. when making payment with a bank card), to a telecom operator (e.g. when passing phone calls with a GSM phone equipped with a SIM card), or to a government organization (e.g. when authenticating with a healthcare smart card, ID smart card, or electronic passport). Many other types of security tokens exist, for example USB keys, parallel port dongles, OTP tokens (OTP stands for One Time Password), TPMs (trusted platform modules, specified by the Trusted Computing Group, and which typically allow to secure a computing device by verifying in particular that the hardware components are not modified, and that any software it runs has the good version and has been properly signed), etc.
During the last decade, the number of security tokens embedding a virtual machine has grown significantly, in particular with the advent of JavaCard, Multos cards, and more recently .NET cards. Such security tokens are advantageous because they can be easily programmed by loading an applet into them (e.g. Java applet, .Net applet, etc.). Due to the fact that security tokens are generally resource constrained, the standards in place (e.g. Java or .NET) had to be adapted (for smart cards, it became JavaCard, and for .NET, a stripped down version of .NET had to be implemented) in order to guarantee that an applet is able to run on the security token. E.G. certain “complex” operations (such as floating point operations) are sometimes not supported.
The JavaCard platform is defined primarily by the following three specifications:                Virtual Machine Specification for the JavaCard™ Platform        Application Programming Interface for the JavaCard™ Platform        Runtime Environment (JCRE) Specification for the JavaCard™ Platform        
The most widespread version of JavaCard is presumably version 2.1, but version 2.2.1 will probably soon become the most widespread. Version 2.2.2 is expected to be the dominant version in the mean term. Version 3 has been released recently but has not yet been widely deployed, it will probably happen a bit later.
A quick overview of the most relevant parts of those specifications is given below.
The JavaCard applet build chain is shown on FIG. 1, it shows the five major steps taking place when building an applet. Each relevant step is described below more in details.
Step 1: Compiling a JavaCard Applet (shown on FIG. 2)
JavaCard applets are written in the Java programming language, using the JavaCard API subset. A standard java compiler is used to generate class files from java files (which are typically text files, written either with a regular text editor, or with a more user friendly environment which can for example automatically highlight certain keywords in certain colors, etc.).
Step 2: Convert the Applet (shown on FIG. 3)
The converter is a tool provided by Sun Microsystems to generate JavaCard conform executable files.
Converter input files are:                one or more class files, which together build a javacard package        one or more export files, if the package has external dependencies to other javacard packages        
Converter output files are:                the package's export file (if the package exports methods, interfaces, classes)        the package's CAP file, which can be loaded on card (in Non Volatile Memory). It is a binary file in compressed format        and/or a JCA file (JavaCard Assembly) file: it is the text representation of a CAP file. Therefore, this file is normally not downloaded on card. It is typically used if the package is to be masked (e.g. in ROM or Flash) with the SmartCard Operating system (see next step).        
Step 3′: “Romize” the package (shown on FIG. 4)
This step is only carried out if it is desired to store the applet in the memory of the card (typically in ROM), in general at chip manufacturing stage. This step is typically performed by a platform specific tool (often called “romizer”), which typically takes all JCA files to “romize” as an input, and links them together in order to generate either an HEX-file that is included in the mask or intermediate files that can be compiled with the Smart Card operating system to generate the complete hardmask with romized packages (also called system libraries). Romizer tools are in general specific to a smart card platform because the link process is strongly tied to the JCVM implementation. The hardmask is typically supplied to a chip manufacturer which can then produce millions of chips comprising the hardmask in question.
Step 3″: Load/install the package on card (shown on FIG. 5)
In this step (which is an alternative to step 3′), the CAP file is not preloaded in the chip, but loaded in the memory of the card (e.g. EEPROM or equivalent memory, e.g. Flash etc.) and therefore the link with the system libraries is performed dynamically by the card, instead of the external romizer tool. Once the CAP is loaded and linked, when executing the program on it, the JCVM behaviour is the same as when executing code in system libraries.
A JavaCard virtual machine instruction consists of an opcode specifying the operation to be performed followed by zero or more operands embodying values to be operated upon. These opcodes are coded on one byte which is the origin of the term bytecode. They are equivalent to a basic assembler instruction for native code. The term “virtual machine” is used because it emulates a processor and its registers with an associated instruction set, composed of all java bytecodes.
The term bytecode is not specific to JavaCard. As explained in particular on Wikipedia, the term bytecode can be used to denote various forms of instruction sets designed for efficient execution by a software interpreter as well as being suitable for further compilation into machine code. Since instructions are processed by software, they may be arbitrarily complex, but are nonetheless often akin to traditional hardware instructions; stack machines are common, for instance. Different parts may often be stored in separate files, similar to object modules, but dynamically loaded during execution. Although the name bytecode stems from instruction sets which have one-byte opcodes followed by optional parameters, bytecodes may have arbitrary formats. Intermediate representations such as bytecode may be output by programming language implementations to ease interpretation, or it may be used to reduce hardware and operating system dependence by allowing the same code to run on different platforms. Bytecode may often be either directly executed on a virtual machine (i.e. interpreter), or it may be further compiled into machine code for better performance.
Unlike human-readable source code, bytecodes are stored in the form of compact numeric codes, constants, references (normally numeric addresses) or other data, which encode the result of parsing and semantic analysis of things like type, scope, and nesting depths of program objects. They therefore allow much better performance than direct interpretation of source code.
A bytecode program is normally executed by parsing the instructions one at a time. This kind of bytecode interpreter is very portable. Some systems, called dynamic translators, or “just-in-time” (JIT) compilers, translate bytecode into machine language as necessary at runtime: this makes the virtual machine unportable, but doesn't lose the portability of the bytecode itself. For example, Java and Smalltalk code is typically stored in bytecoded format, which is typically then JIT compiled to translate the bytecode to machine code before execution. This typically introduces a delay before a program is run, when bytecode is compiled to native machine code, but improves execution speed considerably compared to interpretation—normally by several times.
Because of its performance advantage, today many language implementations execute a program in two phases, first compiling the source code into bytecode, and then passing them to the virtual machine. Therefore, there are virtual machines for Java, Python, PHP, Forth, and Tcl, to name a few. The current reference implementation of Perl and Ruby programming language instead work by walking an abstract syntax tree representation derived from the source code.
Examples of JavaCard bytecodes comprise:                aconst_null (0x01), which pushes the null object reference onto the operand stack        goto (0x70), wherein the value just behind the opcode (bytecode operand) is used as a signed 8-bit offset. Execution proceeds at that offset from the address of the opcode of the goto instruction. The target address must be that of an opcode of an instruction within the method that contains this goto instruction.        
The JavaCard 2.2.1 specifications define 185 bytecodes. These bytecodes take all values between 0 and 184 (0xB8).
There are two important requirements when writing applets for security tokens.
1. The security level should be high, since a security token is supposed to be secure, and for example sensitive data stored in the security token should not be leaked.
2. The overall performance of the security token should remain acceptable, for example for a smart card, an APDU should be executed quickly enough to ensure an acceptable transaction time.
Unfortunately, the two requirements above are in general conflicting, because most often when you increase security you slow down the execution. Enhancing the security of the applet, especially for protecting against fault attacks, may comprise inserting redundancy checks, or multiplying the execution of a given task in order to check that all executions lead to the same result (almost impossible in case of a fault attack), which typically adds executable code and increases execution time.
Conversely, by “optimizing” the applet in order to speed up the execution, the security is often weakened.
These requirements are also complex due to the fact that applets (e.g. Javacard applets) are written in a language (typically interpreted) which is normally supposed to be platform independent. I.E. an applet written by one party (e.g. a smart card manufacturer) should be working on any platform, and not only on the platform initially used by that party (e.g. it should work on the smart card of any other manufacturer), as long as the two platform support the same virtual machine (e.g. same version of Java Virtual Machine—aka JVM—).
So far, three main approaches have been put in place.
1. In a first approach, the whole virtual machine is secured, so the applets may use standard APIs. The resulting executable code is highly portable, but the performances are usually poor as the whole execution is secured instead of focusing on sensitive operations only.
2. In a second approach, the virtual machine is optimized for speed. The security mechanisms embedded in the virtual machine itself are much less powerful than in the first approach. It is up to the applet to rely on proprietary APIs in order to secure its execution, by smartly introducing security mechanisms in the most sensitive parts of the applet. The proprietary API typically provides services securing the execution. The functions provided by such proprietary API typically include:                Inserting randomized delay during the execution is order to make it more complex to synchronize operations needed to attack the card with the execution of the applet.        Managing secure counters for following up the execution of the code.        Monitoring alerts when attacks are detected.        
The use of such proprietary API is typically made at sensitive places of the applet. These proprietary APIs are usually called several times as the applet is running. It is the use of these proprietary APIs that secures the applet. However, such applet is no longer interoperable, as it relies on proprietary APIs which are not necessarily available on any platform. In addition, the security fully relies on the developer of the applet (if the developer does not use the security features, the applet is usually insecure).
Like any other software, smart card ones include branches that are taken depending on tests results during the software execution. In the second approach some of these tests and branches are dedicated to secure the code execution by calling proprietary APIs, and/or to verify security policy enforcement. It is typically a goal of people attacking the smart card to disturb the software execution in order to change the results of some tests, or avoid the execution of some bytecodes. Such attacks can be done in particular by physical means, such as introducing disruption by inserting glitches in the clock, temporarily increasing the power supply, using a laser beam on selected part of the surface of the chip, etc. In the second approach, the applet developers tries to identify sensitive parts of the code, and typically adds some code carrying out verifications in these parts of the code, in order to make the attacker task more complex. But this leads to a bigger executable code size and to inferior performances.
3. In a third approach, described in patent application EP08305900, two sets of functionally equivalent bytecodes are proposed, one set being executed securely while the other set is executed quickly.
According to U.S. patent application Ser. No. 10/451,520 (“Method for making secure execution of a program in a microprocessor-based electronic module”), in order to prevent fault attacks, it is proposed to intermittently (and preferably at random time) trigger an interrupt, wherein the interrupt is empty (immediately or almost immediately followed by a return instruction) and wherein the return is optionally followed by trap instructions for detecting a fault attack. One problem with this technique is that it may monopolize interrupt resources and that it is not really suitable to protect specifically selected functions, as the protection is subject to the occurrence of an interrupt during the selected functions. In other words, either the interrupts according to Ser. No. 10/451,520 are triggered very often (which may pose problems with performance and interrupt management), or it is unknown whether a call to a given function is protected or not (since it is not sure that an interrupt will occur during the call to this function).